package com.daxt.utils;

import com.daxt.model.service.archives.vo.ArchivesAdministrationDoc;
import com.daxt.model.service.archives.vo.ArchivesDoc;
import com.daxt.utils.file.FileBaseUtil;
import org.dom4j.*;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.*;

/**
 * @description: 使用dom4j解析Xml文档
 *
 * @author: lig
 * @date: 2022/7/16
 */
public class XmlDomUtil {

    //用于存放当前目录下所有文件的集合
    public static  Map<String,String> fileMaps=new HashMap<>();

    //用于存放当前目录下所有文件和目录
    public static  Map<String,String> fileMkdirMaps = new HashMap<>();

    /**
     * @description: 根据路径获取当面目录下的所有文件
     *
     * @author: lig
     * @date: 2022/7/16
     */
    public static void getFiles(String xmlFilePath ){
        File file=new File(xmlFilePath);


        //判断是不是一个目录
        if(file.isDirectory()){
            File[] files =file.listFiles();
            for(File file1:files){
                //判读是不是一个文件
                if(file1.isFile()){
                    //若是则保存在map中
                    fileMaps.put(file1.getName(),file1.getAbsolutePath());
                    fileMkdirMaps.put(FileBaseUtil.getFileNameFront(file1.getName()),"1");
                }
                // 判读是不是一个目录
                if(file1.isDirectory()){
                    fileMkdirMaps.put(FileBaseUtil.getFileNameFront(file1.getName()),"1");
                    //若是则进行递归
                    getFiles(file1.getAbsolutePath() );
                }
            }
        }else{
            //判读是不是一个文件
            if(file.isFile()){
                //若是则保存在map中
                fileMaps.put(file.getName(),file.getAbsolutePath());
            }
        }
    }

    /**
     * @description: 获取指定目录下下的所有xml文件
     *
     * @author: lig
     * @date: 2022/7/19
     */
    public  static  List<String> getXmlFiles(String xmlFilePath){
        List<String> xmlFilePaths=getXmlFiles(xmlFilePath ,"xml");
        return xmlFilePaths;
    }

    /**
     * @description: 获取指定目录下的任意文件
     *
     * @author: lig
     * @date: 2022/7/16
     */
    public  static  ArrayList<String> getXmlFiles(String xmlFilePath ,String ext ){
        ArrayList<String> xmlFilePaths =new ArrayList<>();
        //获取当前目录的所有文件
        getFiles(xmlFilePath );
        //遍历所有的文件
        for (Map.Entry<String, String> entry : fileMaps.entrySet()) {
            String mapKey = entry.getKey();
            String mapValue = entry.getValue();
            //获取文件后缀名
            String FileExt= FileBaseUtil.getFileNameExt(mapKey);
            //若不是指定文件结尾则跳过本次循环
            if(!ext.equals(FileExt)){
                continue;
            }
            //保存所有的指定文件
            xmlFilePaths.add(mapValue);
        }
        return xmlFilePaths;
    }

    /**
     * @description: 获取当前元素的属性名与属性值
     *
     * @author: lig
     * @date: 2022/7/16
     */
    public static ArrayList<String> getXmlAttributes(Element element ){
        ArrayList<String> list=new ArrayList<>();
        // 获取当前元素的所有属性
        List listAttributes= element.attributes();
        //判读当前元素有无属性
        if(listAttributes.size()<=0){
            //若当前元素没有属性则直接返回null
            return null;
        }
        //遍历所有的属性
        for(int i=0;i<listAttributes.size();i++){
            Attribute attribute= (Attribute)listAttributes.get(i);
            String attributeName=attribute.getName();
            String attributeValue=attribute.getValue();
            //将属性结果存在list中
            list.add(attributeName);
            list.add(attributeValue);
        }
        return list;
    }

    /**
     * @description: 获取当前层的下层元素的，元素名、元素值、[属性名、属性值}
     *
     * @author: lig
     * @date: 2022/7/16
     */
    public static ArrayList<List<String>> getElements(Element element){

        ArrayList<List<String>> lists=new ArrayList<>();

        //获取当前元素的子元素
        List<Element> listElement= element.elements();
        //遍历所有的子元素
        for(Element elementSon :listElement){
            List<String> list=new ArrayList();
            String elementName= elementSon.getName().trim();
            String elementText= elementSon.getText().trim();

            //获取当前元素的所有属性
            List attributelist = getXmlAttributes(elementSon);

            list.add(elementName);
            list.add(elementText);
            list.add(attributelist+"");
            lists.add(list);
        }
        return lists;
    }

    /**
     * @description: 打印当前层的元素信息
     *
     * @author: lig
     * @date: 2022/7/16
     */
    public static void elementPrintln(List<List<String>> element){
        for(List<String> list:element){
            for(String str:list){
                System.out.println(str);
            }
        }
    }

    /**
     * @description: 使用dom4解析任意xml文件（最多可解析到第5层）
     *
     * @author: lig
     * @date: 2022/7/16
     */
    public static Map<String,List> domXml(String xmlPath){

        Map<String,List> map=new LinkedHashMap<>();

        try{
            //读取XML文件,获得document对象.
            SAXReader reader = new SAXReader();
            Document document = reader.read(new File(xmlPath));
            //获取文档的根节点.
            Element rootElm = document.getRootElement();

            //获取根节点的属性
            List<String> listAttributesRoot = getXmlAttributes(rootElm);

            map.put("0",listAttributesRoot);

            //获取第一层元素的所有元素名、元素值、属性名、属性值
            List<List<String>>  listElementOne = getElements(rootElm);
            map.put("1",listElementOne);

            //对根节点下的所有子节点进行遍历(第一层)
            int i=0;
            for(Iterator it = rootElm.elementIterator(); it.hasNext();){
                Element elementOne = (Element) it.next();

                //获取第二层元素的的所有元素名、元素值、属性名、属性值
                List<List<String>>  listElementTwo = getElements(elementOne);
                //若值为空，则跳过本次循环
                if(listElementTwo.size()<=0){
                    i++;
                    continue;
                }
                map.put("1_"+ i +"->2" ,listElementTwo);

                //获取第一层下的所子节点进行遍历（第二层）
                int j=0;
                for(Iterator it2 = elementOne.elementIterator(); it2.hasNext();){
                    Element listElementTwo2 = (Element) it2.next();

                    //获取第三层元素的的所有元素名、元素值、属性名、属性值
                    List<List<String>>  listElementThree = getElements(listElementTwo2);
                    //若值为空，则跳过本次循环
                    if(listElementThree.size()<=0){
                        j++;
                        continue;
                    }
                    map.put("1_"+i+"->2_"+j+"->3" ,listElementThree);

                    //获取第二层下的所子节点进行遍历（第三层）
                    int k=0;
                    for(Iterator it3 = listElementTwo2.elementIterator(); it3.hasNext();){
                        Element listElementThree2 = (Element) it3.next();
                        //获取第四层元素的的所有元素名、元素值、属性名、属性值
                        List<List<String>>  listElementFour = getElements(listElementThree2);
                        //若值为空，则跳过本次循环
                        if(listElementFour.size()<=0){
                            k++;
                            continue;
                        }

                        //例如：1_5->2_3->3_5->4   表示跟节点下一层（1）的第六个元素（5）的下一层(2)的第四个元素（3）的下一层（3）的
                        //第六个元素（5）的下一层（4）的
                        map.put("1_"+ i +"->2_"+j+"->3_"+k+"->4" ,listElementFour);
                        k++;
                    }
                    j++;
                }
                i++;
            }

        }catch (DocumentException e){
            e.printStackTrace();
        }
        return map;
    }

    public static boolean isArchives(String path){
        getFiles(path );
        Map<String,List> map =domXml(path+"\\归档配置范围.xml");
        Set keyset = map.keySet();
        for(Object key:keyset){
            List list= (List)map.get(key);
            if(!"0".equals(key)){
                for(int i=0;i<list.size();i++){
                    List list2=(List) list.get(i);
                    //System.out.println(list2.get(2));
                    if(list2.get(2)!=null&&("filingrange".equals(list2.get(0))||"filename".equals(list2.get(0)))){
                        String mkdirs= list2.get(2).toString();
                        String[] fileMkdirName= mkdirs.replace("[","").replace("]","").split(",");
                        String val= fileMkdirMaps.get(fileMkdirName[1].trim());
                        if(!"1".equals(val)) return false;
                    }
                }
            }
        }
        return true;
    }

    /**
     * @description: 解析基本信息描述.xml文件并返回ArchivesDoc实例
     *
     * @author: lig
     * @date: 2022/7/19
     */
    public static ArchivesAdministrationDoc getArchivesDocXml(String path){
        ArchivesAdministrationDoc administrationDoc=new ArchivesAdministrationDoc();
        Map<String,List> map =domXml(path+"\\基本信息描述.xml");
        Set keyset = map.keySet();
        for(Object key:keyset){
            List list= (List)map.get(key);
            if(!"0".equals(key)){
                for(int i=0;i<list.size();i++){
                    List list2=(List) list.get(i);
                    //System.out.println(list2.get(0)+","+list2.get(1)+","+list2.get(2));
                    String result= list2.get(0).toString();
                    switch (result){
                        case "receivetime": administrationDoc.setReceiveTime(list2.get(1).toString()); break;
                        case "legalman": administrationDoc.setLegalman(list2.get(1).toString()); break;
                        case "contactidcard": administrationDoc.setContactidcard(list2.get(1).toString());  break;
                        case "version": administrationDoc.setVersion(list2.get(1).toString());  break;
                        case "receivedepartmentname": administrationDoc.setReceiveDepartmentName(list2.get(1).toString());  break;
                        case "archivetime": administrationDoc.setArchiveTime(list2.get(1).toString()); break;
                        case "projectname": administrationDoc.setProjectName(list2.get(1).toString());  break;
                        case "servicetype": administrationDoc.setServiceType(list2.get(1).toString()); break;
                        case "projid": administrationDoc.setProjId(list2.get(1).toString()); break;
                        case "infotype": administrationDoc.setInfoType(list2.get(1).toString()); break;
                        case "transacttime": administrationDoc.setTransactTime(list2.get(1).toString()); break;
                        case "projectpassword": administrationDoc.setProjectPassword(list2.get(1).toString()); break;
                        case "deptname": administrationDoc.setDeptName(list2.get(1).toString()); break;
                        case "eventtype ": administrationDoc.setEventType(list2.get(1).toString()); break;
                        case "phone": administrationDoc.setPhone(list2.get(1).toString()); break;
                        case "result": administrationDoc.setResult(list2.get(1).toString()); break;
                        case "retentionperiod": administrationDoc.setRetentionPeriod(list2.get(1).toString()); break;
                        case "resultcode": administrationDoc.setResultCode(list2.get(1).toString()); break;
                        case "eventcode": administrationDoc.setEventCode(list2.get(1).toString()); break;
                        default:
                    }
                }
            }
        }
        return administrationDoc;
    }



    /*public static void main(String[] args) {
       *//* List<String> xmlFilePaths= getXmlFiles("F:\\zjq\\33000019-01-00190-003-2017-5年-0035032");
        for(String xmlFilePath:xmlFilePaths){
            System.out.println(xmlFilePath);
        }*//*

        Map<String,List> mapDoc = XmlDomUtil.domXml("C:/Users/admin/Desktop/ZB-LX-346fc765-508f-11ee-9fed-93472c7d0531/ZB-LX-346fc765-508f-11ee-9fed-93472c7d0531-1/346fc765-508f-11ee-9fed-93472c7d0531/doc.xml");
        for(String key:mapDoc.keySet()) {
            //String regex = "1_4->2_[\\d]->3";
            String regex = "1_4->2_([0-9][0-9]{0,1}|100)->3";

            if (!key.matches(regex)) {
                continue;
            }
            List<List<String>> listThree = mapDoc.get(key);

            System.out.println(key+":"+mapDoc.get(key));
            for (int j = 0; j < listThree.size(); j++) {
                List<String> list = listThree.get(j);
                if (j == 3) {
                    //listFileName.add(list.get(1));  //文件名
                    System.out.println("文件名:"+list.get(1));
                }
                if (j == 7) {
                    //listFilePath.add(list.get(1));
                    System.out.println("文件路径:"+list.get(1));
                    System.out.println();
                }

            }


        }
        //System.out.println(isArchives("F:\\zjq\\33000019-01-00190-003-2017-5年-0035032"));
    }*/
}
